package org.ehe.business.bom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.ehe.business.bom.domain.BomChangeLog;
import org.ehe.business.bom.domain.BomMaster;
import org.ehe.business.bom.domain.BomStructure;
import org.ehe.business.bom.domain.BomVersion;
import org.ehe.business.bom.domain.bo.BomChangeLogBo;
import org.ehe.business.bom.domain.vo.BomChangeLogVO;
import org.ehe.business.bom.mapper.BomChangeLogMapper;
import org.ehe.business.bom.service.BomChangeLogService;
import org.ehe.business.bom.service.BomMasterService;
import org.ehe.business.bom.service.BomStructureService;
import org.ehe.business.bom.service.BomVersionService;
import org.ehe.business.engineer.domain.EngineerEntity;
import org.ehe.business.engineer.domain.vo.EngineerEntityVO;
import org.ehe.common.core.constant.StatusEnum;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author :zhangnn
 * @className :BomChangeLogServiceImpl
 * @description: TODO
 * @date 2025-07-30 14:08:51
 */
@Slf4j
@Service
public class BomChangeLogServiceImpl extends ServiceImpl<BomChangeLogMapper, BomChangeLog> implements BomChangeLogService {
    @Autowired
    private BomMasterService bomMasterService;

    @Autowired
    private BomVersionService bomVersionService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private BomStructureService bomStructureService;

    /**
     * 分页列表
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<BomChangeLogVO> pageChangeLogs(BomChangeLogBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BomChangeLog> lqw = new LambdaQueryWrapper<BomChangeLog>()
            .eq(BomChangeLog::getChangeType, bo.getChangeType())
            .orderByDesc(BomChangeLog::getCreateTime);
        Page<BomChangeLogVO> list = this.baseMapper.selectVoPage(pageQuery.build(),lqw);
        return TableDataInfo.build(list);
    }

    /**
     * 创建BOM变更记录
     */
    @Transactional
    public BomChangeLog createChangeRequest(BomChangeLog changeLog) {
        log.info("创建BOM变更记录: bomId={}, changeType={}", changeLog.getBomId(), changeLog.getChangeType());

        // 验证变更请求
        validateChangeRequest(changeLog);

        // 设置初始状态
        changeLog.setChangeStatus(1); // 待审批
        changeLog.setApplyTime(new Date());
        changeLog.setCreateTime(new Date());

        this.save(changeLog);

        log.info("BOM变更记录创建成功: changeLogId={}", changeLog.getId());
        return changeLog;
    }

    /**
     * 提交变更审批
     */
    @Transactional
    public void submitChangeForApproval(Long changeLogId, Long workflowInstanceId) {
        log.info("提交BOM变更审批: changeLogId={}, workflowInstanceId={}", changeLogId, workflowInstanceId);

        BomChangeLog changeLog = this.getById(changeLogId);
        if (changeLog == null) {
            throw new RuntimeException("变更记录不存在");
        }

        if (changeLog.getChangeStatus() != 1) {
            throw new RuntimeException("只有待审批状态的变更才能提交审批");
        }

        changeLog.setWorkflowInstanceId(workflowInstanceId);
        changeLog.setUpdateTime(new Date());
        this.updateById(changeLog);

        log.info("BOM变更提交审批成功: changeLogId={}", changeLogId);
    }

    /**
     * 审批通过变更请求
     */
    @Transactional
    public void approveChange(Long changeLogId, Long approverId, String approverName, String approvalComments) {
        log.info("审批通过BOM变更: changeLogId={}, approverId={}", changeLogId, approverId);

        BomChangeLog changeLog = this.getById(changeLogId);
        if (changeLog == null) {
            throw new RuntimeException("变更记录不存在");
        }

        if (changeLog.getChangeStatus() != 1) {
            throw new RuntimeException("只有待审批状态的变更才能审批通过");
        }

        Date now = new Date();

        // 更新变更记录状态
        changeLog.setChangeStatus(2); // 已批准
        changeLog.setApproverId(approverId);
        changeLog.setApproverName(approverName);
        changeLog.setApproveTime(now);
        changeLog.setUpdateTime(now);

        // 添加审批意见到变更内容
        addApprovalComments(changeLog, approvalComments);

        this.updateById(changeLog);

        log.info("BOM变更审批通过成功: changeLogId={}", changeLogId);
    }

    /**
     * 拒绝变更请求
     */
    @Transactional
    public void rejectChange(Long changeLogId, Long approverId, String approverName, String rejectReason) {
        log.info("拒绝BOM变更: changeLogId={}, approverId={}, reason={}", changeLogId, approverId, rejectReason);

        BomChangeLog changeLog = this.getById(changeLogId);
        if (changeLog == null) {
            throw new RuntimeException("变更记录不存在");
        }

        if (changeLog.getChangeStatus() != 1) {
            throw new RuntimeException("只有待审批状态的变更才能拒绝");
        }

        Date now = new Date();

        changeLog.setChangeStatus(3); // 已拒绝
        changeLog.setApproverId(approverId);
        changeLog.setApproverName(approverName);
        changeLog.setApproveTime(now);
        changeLog.setChangeReason(changeLog.getChangeReason() + " [拒绝原因: " + rejectReason + "]");
        changeLog.setUpdateTime(now);

        this.updateById(changeLog);

        log.info("BOM变更拒绝成功: changeLogId={}", changeLogId);
    }

    /**
     * 实施变更
     */
    @Transactional
    public void implementChange(Long changeLogId) {
        log.info("实施BOM变更: changeLogId={}", changeLogId);

        BomChangeLog changeLog = this.getById(changeLogId);
        if (changeLog == null) {
            throw new RuntimeException("变更记录不存在");
        }

        if (changeLog.getChangeStatus() != 2) {
            throw new RuntimeException("只有已批准的变更才能实施");
        }

        try {
            // 根据变更类型执行相应的变更操作
            executeChange(changeLog);

            // 更新变更状态为已实施
            changeLog.setChangeStatus(4);
            changeLog.setImplementTime(new Date());
            changeLog.setUpdateTime(new Date());
            this.updateById(changeLog);

            log.info("BOM变更实施成功: changeLogId={}", changeLogId);

        } catch (Exception e) {
            log.error("BOM变更实施失败: changeLogId={}", changeLogId, e);
            throw new RuntimeException("变更实施失败: " + e.getMessage());
        }
    }

    /**
     * 执行具体的变更操作
     */
    private void executeChange(BomChangeLog changeLog) throws JsonProcessingException {
        Integer changeType = changeLog.getChangeType();
        Integer changeObject = changeLog.getChangeObject();

        switch (changeType) {
            case 1: // 新增
                executeAddChange(changeLog, changeObject);
                break;
            case 2: // 修改
                executeModifyChange(changeLog, changeObject);
                break;
            case 3: // 删除
                executeDeleteChange(changeLog, changeObject);
                break;
            case 4: // 替换
                executeReplaceChange(changeLog, changeObject);
                break;
            default:
                throw new RuntimeException("不支持的变更类型: " + changeType);
        }
    }

    /**
     * 执行新增变更
     */
    private void executeAddChange(BomChangeLog changeLog, Integer changeObject) throws JsonProcessingException {
        Map<String, Object> changeContent = parseChangeContent(changeLog.getChangeContent());

        switch (changeObject) {
            case 1: // BOM基本信息
                // 创建新的BOM或版本
                createNewBomFromChange(changeLog, changeContent);
                break;
            case 2: // BOM结构
                // 添加新的结构项
                addBomStructureFromChange(changeLog, changeContent);
                break;
            case 3: // 物料信息
                // 更新物料相关信息
                updateMaterialInfoFromChange(changeLog, changeContent);
                break;
        }
    }

    /**
     * 执行修改变更
     */
    private void executeModifyChange(BomChangeLog changeLog, Integer changeObject) throws JsonProcessingException {
        Map<String, Object> changeContent = parseChangeContent(changeLog.getChangeContent());

        // 根据变更对象执行不同的修改操作
        switch (changeObject) {
            case 1: // BOM基本信息
                modifyBomBasicInfo(changeLog, changeContent);
                break;
            case 2: // BOM结构
                modifyBomStructure(changeLog, changeContent);
                break;
            case 3: // 物料信息
                modifyMaterialInfo(changeLog, changeContent);
                break;
        }
    }

    /**
     * 执行删除变更
     */
    private void executeDeleteChange(BomChangeLog changeLog, Integer changeObject) throws JsonProcessingException {
        Map<String, Object> changeContent = parseChangeContent(changeLog.getChangeContent());

        // 实现删除逻辑
        log.info("执行删除变更: changeLogId={}, changeObject={}", changeLog.getId(), changeObject);

        try {
            switch (changeObject) {
                case 1: // BOM基本信息 - 通常是废弃整个BOM
                    deleteBomBasicInfo(changeLog, changeContent);
                    break;
                case 2: // BOM结构 - 删除特定结构项
                    deleteBomStructureItems(changeLog, changeContent);
                    break;
                case 3: // 物料信息 - 从BOM中移除特定物料
                    deleteMaterialFromBom(changeLog, changeContent);
                    break;
                default:
                    throw new RuntimeException("不支持的删除对象类型: " + changeObject);
            }
        } catch (Exception e) {
            log.error("执行删除变更失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("执行删除变更失败: " + e.getMessage());
        }
    }

    /**
     * 执行替换变更
     */
    private void executeReplaceChange(BomChangeLog changeLog, Integer changeObject) throws JsonProcessingException {
        Map<String, Object> changeContent = parseChangeContent(changeLog.getChangeContent());

        // 实现替换逻辑
        log.info("执行替换变更: changeLogId={}, changeObject={}", changeLog.getId(), changeObject);
        try {
            switch (changeObject) {
                case 1: // BOM基本信息替换
                    replaceBomBasicInfo(changeLog, changeContent);
                    break;
                case 2: // BOM结构替换
                    replaceBomStructure(changeLog, changeContent);
                    break;
                case 3: // 物料替换
                    replaceMaterialInBom(changeLog, changeContent);
                    break;
                default:
                    throw new RuntimeException("不支持的替换对象类型: " + changeObject);
            }
        } catch (Exception e) {
            log.error("执行替换变更失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("执行替换变更失败: " + e.getMessage());
        }
    }

    /**
     * 获取或创建目标版本
     */
    private BomVersion getOrCreateTargetVersion(BomChangeLog changeLog) {
        if (changeLog.getNewVersionId() != null) {
            return bomVersionService.getById(changeLog.getNewVersionId());
        }

        // 创建新版本
        BomVersion newVersion = bomVersionService.createNewVersion(
            changeLog.getBomId(),
            changeLog.getChangeReason(),
            changeLog.getChangeDescription()
        );

        // 更新变更记录
        changeLog.setNewVersionId(newVersion.getId());
        this.updateById(changeLog);

        return newVersion;
    }

    /**
     * 解析变更内容JSON
     */
    @SuppressWarnings("unchecked")
    private Map<String, Object> parseChangeContent(String changeContent) throws JsonProcessingException {
        if (changeContent == null || changeContent.trim().isEmpty()) {
            return new HashMap<>();
        }
        return objectMapper.readValue(changeContent, Map.class);
    }

    /**
     * 从变更记录创建新BOM
     */
    private void createNewBomFromChange(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 创建新版本
        BomVersion newVersion = bomVersionService.createNewVersion(
            changeLog.getBomId(),
            changeLog.getChangeReason(),
            changeLog.getChangeDescription()
        );

        // 更新变更记录的新版本ID
        changeLog.setNewVersionId(newVersion.getId());
    }

    /**
     * 添加BOM结构项
     */
    private void addBomStructureFromChange(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 实现添加结构项的逻辑
        log.info("添加BOM结构项: changeLogId={}", changeLog.getId());
        try {
            // 获取或创建新版本
            BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

            // 从变更内容中解析新增的结构项信息
            List<Map<String, Object>> newItems = (List<Map<String, Object>>) changeContent.get("newItems");
            if (newItems == null || newItems.isEmpty()) {
                throw new RuntimeException("未找到要添加的结构项信息");
            }

            for (Map<String, Object> itemData : newItems) {
                BomStructure newStructure = new BomStructure();
                newStructure.setBomVersionId(targetVersion.getId());

                // 设置基本信息
                setStructureBasicInfo(newStructure, itemData);

                // 设置层级和序号
                setStructureHierarchy(newStructure, itemData, targetVersion.getId());

                // 设置供应商和价格信息
                setStructureSupplierInfo(newStructure, itemData);

                // 设置其他属性
                setStructureOtherInfo(newStructure, itemData);

                // 保存新结构项
                bomStructureService.save(newStructure);

                log.info("新增BOM结构项成功: itemCode={}, itemName={}",
                    newStructure.getItemCode(), newStructure.getItemName());
            }

            // 更新版本的修改时间
            targetVersion.setUpdateTime(new Date());
            bomVersionService.updateById(targetVersion);

        } catch (Exception e) {
            log.error("添加BOM结构项失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("添加BOM结构项失败: " + e.getMessage());
        }
    }

    /**
     * 更新物料信息
     */
    private void updateMaterialInfoFromChange(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 实现更新物料信息的逻辑
        log.info("更新物料信息: changeLogId={}", changeLog.getId());
        try {
            // 获取要更新的物料信息
            List<Map<String, Object>> updateItems = (List<Map<String, Object>>) changeContent.get("updateItems");
            if (updateItems == null || updateItems.isEmpty()) {
                throw new RuntimeException("未找到要更新的物料信息");
            }

            BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

            for (Map<String, Object> itemData : updateItems) {
                Long structureId = getLongValue(itemData, "structureId");
                if (structureId == null) {
                    continue;
                }

                BomStructure structure = bomStructureService.getById(structureId);
                if (structure == null) {
                    log.warn("BOM结构项不存在: structureId={}", structureId);
                    continue;
                }

                // 如果是不同版本的结构项，需要复制到新版本
                if (!structure.getBomVersionId().equals(targetVersion.getId())) {
                    structure = copyStructureToNewVersion(structure, targetVersion.getId());
                }

                // 更新物料基本信息
                updateStructureBasicInfo(structure, itemData);

                // 更新数量和损耗率
                updateStructureQuantityInfo(structure, itemData);

                // 更新供应商和价格信息
                updateStructureSupplierInfo(structure, itemData);

                // 更新其他物料属性
                updateStructureOtherInfo(structure, itemData);

                structure.setUpdateTime(new Date());
                bomStructureService.updateById(structure);

                log.info("更新物料信息成功: itemCode={}, structureId={}",
                    structure.getItemCode(), structure.getId());
            }

        } catch (Exception e) {
            log.error("更新物料信息失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("更新物料信息失败: " + e.getMessage());
        }
    }

    /**
     * 更新数量和损耗率信息
     * @param structure
     * @param itemData
     */
    private void updateStructureQuantityInfo(BomStructure structure, Map<String, Object> itemData) {
        if (itemData.containsKey("quantity")) {
            BigDecimal newQuantity = getBigDecimalValue(itemData, "quantity");
            if (newQuantity != null) {
                structure.setQuantity(newQuantity);
                // 重新计算总价
                if (structure.getUnitPrice() != null) {
                    structure.setTotalPrice(newQuantity.multiply(structure.getUnitPrice()));
                }
            }
        }
        if (itemData.containsKey("scrapRate")) {
            structure.setScrapRate(getBigDecimalValue(itemData, "scrapRate"));
        }
    }

    /**
     * 更新供应商和价格信息
     */
    private void updateStructureSupplierInfo(BomStructure structure, Map<String, Object> itemData) {
        if (itemData.containsKey("supplierId")) {
            structure.setSupplierId(getLongValue(itemData, "supplierId"));
        }
        if (itemData.containsKey("supplierName")) {
            structure.setSupplierName(getStringValue(itemData, "supplierName"));
        }
        if (itemData.containsKey("unitPrice")) {
            BigDecimal newUnitPrice = getBigDecimalValue(itemData, "unitPrice");
            if (newUnitPrice != null) {
                structure.setUnitPrice(newUnitPrice);
                // 重新计算总价
                if (structure.getQuantity() != null) {
                    structure.setTotalPrice(structure.getQuantity().multiply(newUnitPrice));
                }
            }
        }
        if (itemData.containsKey("totalPrice")) {
            structure.setTotalPrice(getBigDecimalValue(itemData, "totalPrice"));
        }
        if (itemData.containsKey("leadTime")) {
            structure.setLeadTime(getIntegerValue(itemData, "leadTime"));
        }
    }

    /**
     * 更新其他物料属性
     */
    private void updateStructureOtherInfo(BomStructure structure, Map<String, Object> itemData) {
        if (itemData.containsKey("isKeyItem")) {
            structure.setIsKeyItem(getIntegerValue(itemData, "isKeyItem"));
        }
        if (itemData.containsKey("isOptional")) {
            structure.setIsOptional(getIntegerValue(itemData, "isOptional"));
        }
        if (itemData.containsKey("substituteGroup")) {
            structure.setSubstituteGroup(getStringValue(itemData, "substituteGroup"));
        }
        if (itemData.containsKey("remark")) {
            structure.setRemark(getStringValue(itemData, "remark"));
        }
    }

    /**
     * 记录基本信息变更历史
     */
    private void recordBasicInfoChange(BomChangeLog changeLog, Map<String, Object> originalInfo,
                                       Map<String, Object> changeContent) {
        try {
            Map<String, Object> changeHistory = new HashMap<>();
            changeHistory.put("changeType", "basicInfoModify");
            changeHistory.put("originalValues", originalInfo);
            changeHistory.put("newValues", changeContent);
            changeHistory.put("changeTime", new Date());

            // 将变更历史保存到变更记录的详细内容中
            Map<String, Object> existingContent = parseChangeContent(changeLog.getChangeContent());
            if (existingContent.get("changeHistory") == null) {
                existingContent.put("changeHistory", new ArrayList<>());
            }

            @SuppressWarnings("unchecked")
            List<Map<String, Object>> historyList =
                (List<Map<String, Object>>) existingContent.get("changeHistory");
            historyList.add(changeHistory);

            changeLog.setChangeContent(objectMapper.writeValueAsString(existingContent));

            log.info("记录基本信息变更历史: changeLogId={}", changeLog.getId());

        } catch (Exception e) {
            log.warn("记录基本信息变更历史失败: {}", e.getMessage());
        }
    }

    /**
     * 处理层级变更
     */
    private void processHierarchyChanges(BomChangeLog changeLog, BomVersion targetVersion,
                                         List<Map<String, Object>> hierarchyChanges) {
        log.info("处理层级变更: changeLogId={}, versionId={}", changeLog.getId(), targetVersion.getId());

        for (Map<String, Object> change : hierarchyChanges) {
            Long structureId = getLongValue(change, "structureId");
            Integer newLevelNo = getIntegerValue(change, "newLevelNo");

            if (structureId != null && newLevelNo != null) {
                BomStructure structure = bomStructureService.getById(structureId);
                if (structure != null) {
                    // 确保在正确版本中操作
                    if (!structure.getBomVersionId().equals(targetVersion.getId())) {
                        structure = copyStructureToNewVersion(structure, targetVersion.getId());
                    }

                    Integer oldLevelNo = structure.getLevelNo();
                    structure.setLevelNo(newLevelNo);
                    structure.setUpdateTime(new Date());
                    bomStructureService.updateById(structure);

                    log.info("更新层级: structureId={}, oldLevel={}, newLevel={}",
                        structureId, oldLevelNo, newLevelNo);
                }
            }
        }
    }
    /**
     * 处理父子关系变更
     */
    private void processParentChildChanges(BomChangeLog changeLog, BomVersion targetVersion,
                                           List<Map<String, Object>> parentChildChanges) {
        log.info("处理父子关系变更: changeLogId={}, versionId={}", changeLog.getId(), targetVersion.getId());

        for (Map<String, Object> change : parentChildChanges) {
            Long structureId = getLongValue(change, "structureId");
            Long newParentItemId = getLongValue(change, "newParentItemId");

            if (structureId != null) {
                BomStructure structure = bomStructureService.getById(structureId);
                if (structure != null) {
                    // 确保在正确版本中操作
                    if (!structure.getBomVersionId().equals(targetVersion.getId())) {
                        structure = copyStructureToNewVersion(structure, targetVersion.getId());
                    }

                    Long oldParentItemId = structure.getParentItemId();
                    structure.setParentItemId(newParentItemId);

                    // 重新计算层级
                    if (newParentItemId == null) {
                        structure.setLevelNo(1); // 顶级物料
                    } else {
                        // 根据新父项计算层级
                        Integer parentLevel = getParentLevel(newParentItemId, targetVersion.getId());
                        structure.setLevelNo(parentLevel != null ? parentLevel + 1 : 1);
                    }

                    structure.setUpdateTime(new Date());
                    bomStructureService.updateById(structure);

                    log.info("更新父子关系: structureId={}, oldParent={}, newParent={}",
                        structureId, oldParentItemId, newParentItemId);
                }
            }
        }
    }

    /**
     * 处理序号变更
     */
    private void processSequenceChanges(BomChangeLog changeLog, BomVersion targetVersion,
                                        List<Map<String, Object>> sequenceChanges) {
        log.info("处理序号变更: changeLogId={}, versionId={}", changeLog.getId(), targetVersion.getId());

        for (Map<String, Object> change : sequenceChanges) {
            Long structureId = getLongValue(change, "structureId");
            Integer newSeqNo = getIntegerValue(change, "newSeqNo");

            if (structureId != null && newSeqNo != null) {
                BomStructure structure = bomStructureService.getById(structureId);
                if (structure != null) {
                    // 确保在正确版本中操作
                    if (!structure.getBomVersionId().equals(targetVersion.getId())) {
                        structure = copyStructureToNewVersion(structure, targetVersion.getId());
                    }

                    Integer oldSeqNo = structure.getSeqNo();
                    structure.setSeqNo(newSeqNo);
                    structure.setUpdateTime(new Date());
                    bomStructureService.updateById(structure);

                    log.info("更新序号: structureId={}, oldSeq={}, newSeq={}",
                        structureId, oldSeqNo, newSeqNo);
                }
            }
        }
    }

    /**
     * 处理替代组变更
     */
    private void processSubstituteGroupChanges(BomChangeLog changeLog, BomVersion targetVersion,
                                               List<Map<String, Object>> substituteGroupChanges) {
        log.info("处理替代组变更: changeLogId={}, versionId={}", changeLog.getId(), targetVersion.getId());

        for (Map<String, Object> change : substituteGroupChanges) {
            Long structureId = getLongValue(change, "structureId");
            String newSubstituteGroup = getStringValue(change, "newSubstituteGroup");

            if (structureId != null) {
                BomStructure structure = bomStructureService.getById(structureId);
                if (structure != null) {
                    // 确保在正确版本中操作
                    if (!structure.getBomVersionId().equals(targetVersion.getId())) {
                        structure = copyStructureToNewVersion(structure, targetVersion.getId());
                    }

                    String oldSubstituteGroup = structure.getSubstituteGroup();
                    structure.setSubstituteGroup(newSubstituteGroup);
                    structure.setUpdateTime(new Date());
                    bomStructureService.updateById(structure);

                    log.info("更新替代组: structureId={}, oldGroup={}, newGroup={}",
                        structureId, oldSubstituteGroup, newSubstituteGroup);
                }
            }
        }
    }
    /**
     * 重新计算层级编号
     */
    private void recalculateLevelNumbers(Long versionId) {
        log.info("重新计算层级编号: versionId={}", versionId);

        try {
            // 获取该版本的所有结构项
            QueryWrapper<BomStructure> wrapper = new QueryWrapper<>();
            wrapper.eq("bom_version_id", versionId)
                .orderBy(true, true, "parent_item_id", "seq_no");

            List<BomStructure> allStructures = bomStructureService.list(wrapper);

            // 使用递归方式重新计算层级
            Map<Long, Integer> itemLevelMap = new HashMap<>();

            // 先处理顶级物料（parent_item_id为null的）
            for (BomStructure structure : allStructures) {
                if (structure.getParentItemId() == null) {
                    structure.setLevelNo(1);
                    itemLevelMap.put(structure.getItemId(), 1);
                    bomStructureService.updateById(structure);
                }
            }

            // 递归处理子级物料
            boolean hasChanges = true;
            int maxIterations = 10; // 防止无限循环
            int iteration = 0;

            while (hasChanges && iteration < maxIterations) {
                hasChanges = false;
                iteration++;

                for (BomStructure structure : allStructures) {
                    if (structure.getParentItemId() != null && structure.getLevelNo() == null) {
                        Integer parentLevel = itemLevelMap.get(structure.getParentItemId());
                        if (parentLevel != null) {
                            int newLevel = parentLevel + 1;
                            structure.setLevelNo(newLevel);
                            itemLevelMap.put(structure.getItemId(), newLevel);
                            bomStructureService.updateById(structure);
                            hasChanges = true;
                        }
                    }
                }
            }

            log.info("层级编号重新计算完成: versionId={}, iterations={}", versionId, iteration);

        } catch (Exception e) {
            log.error("重新计算层级编号失败: versionId={}", versionId, e);
            throw new RuntimeException("重新计算层级编号失败: " + e.getMessage());
        }
    }
    /**
     * 记录原始值用于变更历史
     */
    private Map<String, Object> recordOriginalValues(BomStructure structure) {
        Map<String, Object> originalValues = new HashMap<>();
        originalValues.put("itemCode", structure.getItemCode());
        originalValues.put("itemName", structure.getItemName());
        originalValues.put("itemType", structure.getItemType());
        originalValues.put("specification", structure.getSpecification());
        originalValues.put("unit", structure.getUnit());
        originalValues.put("quantity", structure.getQuantity());
        originalValues.put("scrapRate", structure.getScrapRate());
        originalValues.put("unitPrice", structure.getUnitPrice());
        originalValues.put("totalPrice", structure.getTotalPrice());
        originalValues.put("supplierId", structure.getSupplierId());
        originalValues.put("supplierName", structure.getSupplierName());
        originalValues.put("leadTime", structure.getLeadTime());
        originalValues.put("isKeyItem", structure.getIsKeyItem());
        originalValues.put("isOptional", structure.getIsOptional());
        originalValues.put("substituteGroup", structure.getSubstituteGroup());
        originalValues.put("remark", structure.getRemark());
        return originalValues;
    }

    /**
     * 记录物料变更历史
     */
    private void recordMaterialChange(BomChangeLog changeLog, BomStructure structure,
                                      Map<String, Object> originalValues, Map<String, Object> changes) {
        try {
            Map<String, Object> changeRecord = new HashMap<>();
            changeRecord.put("changeType", "materialModify");
            changeRecord.put("structureId", structure.getId());
            changeRecord.put("itemCode", structure.getItemCode());
            changeRecord.put("originalValues", originalValues);
            changeRecord.put("changes", changes);
            changeRecord.put("changeTime", new Date());

            // 将变更记录保存到变更内容中
            Map<String, Object> existingContent = parseChangeContent(changeLog.getChangeContent());
            if (existingContent.get("materialChangeHistory") == null) {
                existingContent.put("materialChangeHistory", new ArrayList<>());
            }

            @SuppressWarnings("unchecked")
            List<Map<String, Object>> historyList =
                (List<Map<String, Object>>) existingContent.get("materialChangeHistory");
            historyList.add(changeRecord);

            changeLog.setChangeContent(objectMapper.writeValueAsString(existingContent));

            log.info("记录物料变更历史: structureId={}, itemCode={}",
                structure.getId(), structure.getItemCode());

        } catch (Exception e) {
            log.warn("记录物料变更历史失败: {}", e.getMessage());
        }
    }

    /**
     * 获取下一个序号
     */
    private Integer getNextSequenceNumber(Long versionId, Long parentItemId) {
        QueryWrapper<BomStructure> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_version_id", versionId);

        if (parentItemId != null) {
            wrapper.eq("parent_item_id", parentItemId);
        } else {
            wrapper.isNull("parent_item_id");
        }

        wrapper.orderByDesc("seq_no").last("LIMIT 1");

        BomStructure lastStructure = bomStructureService.getOne(wrapper);

        return (lastStructure != null && lastStructure.getSeqNo() != null)
            ? lastStructure.getSeqNo() + 1
            : 1;
    }

    /**
     * 检查并处理子项
     */
    private void checkAndHandleChildItems(BomStructure parentStructure, Long versionId) {
        QueryWrapper<BomStructure> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_version_id", versionId)
            .eq("parent_item_id", parentStructure.getItemId());

        List<BomStructure> childItems = bomStructureService.list(wrapper);

        if (!childItems.isEmpty()) {
            log.warn("结构项 {} 有 {} 个子项，需要先处理子项",
                parentStructure.getItemCode(), childItems.size());

            // 可以选择递归删除子项，或者抛出异常要求用户先处理
            for (BomStructure child : childItems) {
                checkAndHandleChildItems(child, versionId);
                bomStructureService.removeById(child.getId());
                log.info("删除子项: structureId={}, itemCode={}", child.getId(), child.getItemCode());
            }
        }
    }

    /**
     * 获取父项层级
     */
    private Integer getParentLevel(Long parentItemId, Long versionId) {
        if (parentItemId == null) {
            return 0;
        }

        QueryWrapper<BomStructure> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_version_id", versionId)
            .eq("item_id", parentItemId);

        BomStructure parentStructure = bomStructureService.getOne(wrapper);

        return (parentStructure != null) ? parentStructure.getLevelNo() : 0;
    }

    /**
     * 更新结构项基本信息
     * @param structure
     * @param itemData
     */
    private void updateStructureBasicInfo(BomStructure structure, Map<String, Object> itemData) {
        if (itemData.containsKey("itemCode")) {
            structure.setItemCode(getStringValue(itemData, "itemCode"));
        }
        if (itemData.containsKey("itemName")) {
            structure.setItemName(getStringValue(itemData, "itemName"));
        }
        if (itemData.containsKey("itemType")) {
            structure.setItemType(getIntegerValue(itemData, "itemType"));
        }
        if (itemData.containsKey("specification")) {
            structure.setSpecification(getStringValue(itemData, "specification"));
        }
        if (itemData.containsKey("unit")) {
            structure.setUnit(getStringValue(itemData, "unit"));
        }
    }

    /**
     * 修改BOM基本信息
     */
    private void modifyBomBasicInfo(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 实现修改BOM基本信息的逻辑
        log.info("修改BOM基本信息: changeLogId={}", changeLog.getId());
        try {
            BomMaster bomMaster = bomMasterService.getById(changeLog.getBomId());
            if (bomMaster == null) {
                throw new RuntimeException("BOM主表记录不存在");
            }

            // 备份原始信息用于记录变更
            Map<String, Object> originalInfo = new HashMap<>();
            originalInfo.put("bomName", bomMaster.getBomName());
            originalInfo.put("projectId", bomMaster.getProjectId());
            originalInfo.put("projectName", bomMaster.getProjectName());
            originalInfo.put("solutionId", bomMaster.getSolutionId());
            originalInfo.put("solutionName", bomMaster.getSolutionName());
            originalInfo.put("bomType", bomMaster.getBomType());
            originalInfo.put("remark", bomMaster.getRemark());

            // 更新BOM基本信息
            if (changeContent.containsKey("bomName")) {
                bomMaster.setBomName(getStringValue(changeContent, "bomName"));
            }
            if (changeContent.containsKey("projectId")) {
                bomMaster.setProjectId(getLongValue(changeContent, "projectId"));
            }
            if (changeContent.containsKey("projectName")) {
                bomMaster.setProjectName(getStringValue(changeContent, "projectName"));
            }
            if (changeContent.containsKey("solutionId")) {
                bomMaster.setSolutionId(getLongValue(changeContent, "solutionId"));
            }
            if (changeContent.containsKey("solutionName")) {
                bomMaster.setSolutionName(getStringValue(changeContent, "solutionName"));
            }
            if (changeContent.containsKey("bomType")) {
                bomMaster.setBomType(getIntegerValue(changeContent, "bomType"));
            }
            if (changeContent.containsKey("remark")) {
                bomMaster.setRemark(getStringValue(changeContent, "remark"));
            }
            if (changeContent.containsKey("effectiveDate")) {
                bomMaster.setEffectiveDate(getDateValue(changeContent, "effectiveDate"));
            }
            if (changeContent.containsKey("expireDate")) {
                bomMaster.setExpireDate(getDateValue(changeContent, "expireDate"));
            }

            bomMaster.setUpdateTime(new Date());
            bomMasterService.updateById(bomMaster);

            // 记录变更历史
            recordBasicInfoChange(changeLog, originalInfo, changeContent);

            log.info("修改BOM基本信息成功: bomId={}, bomCode={}", bomMaster.getId(), bomMaster.getBomCode());

        } catch (Exception e) {
            log.error("修改BOM基本信息失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("修改BOM基本信息失败: " + e.getMessage());
        }
    }

    /**
     * 修改BOM结构
     */
    private void modifyBomStructure(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 实现修改BOM结构的逻辑
        log.info("修改BOM结构: changeLogId={}", changeLog.getId());
        try {
            BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

            // 处理结构层级调整
            if (changeContent.containsKey("hierarchyChanges")) {
                processHierarchyChanges(changeLog, targetVersion,
                    (List<Map<String, Object>>) changeContent.get("hierarchyChanges"));
            }

            // 处理父子关系调整
            if (changeContent.containsKey("parentChildChanges")) {
                processParentChildChanges(changeLog, targetVersion,
                    (List<Map<String, Object>>) changeContent.get("parentChildChanges"));
            }

            // 处理序号调整
            if (changeContent.containsKey("sequenceChanges")) {
                processSequenceChanges(changeLog, targetVersion,
                    (List<Map<String, Object>>) changeContent.get("sequenceChanges"));
            }

            // 处理替代组调整
            if (changeContent.containsKey("substituteGroupChanges")) {
                processSubstituteGroupChanges(changeLog, targetVersion,
                    (List<Map<String, Object>>) changeContent.get("substituteGroupChanges"));
            }

            // 重新计算层级编号
            recalculateLevelNumbers(targetVersion.getId());

            log.info("修改BOM结构成功: changeLogId={}, versionId={}",
                changeLog.getId(), targetVersion.getId());

        } catch (Exception e) {
            log.error("修改BOM结构失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("修改BOM结构失败: " + e.getMessage());
        }
    }

    /**
     * 修改物料信息
     */
    private void modifyMaterialInfo(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 实现修改物料信息的逻辑
        log.info("修改物料信息: changeLogId={}", changeLog.getId());
        try {
            List<Map<String, Object>> materialChanges =
                (List<Map<String, Object>>) changeContent.get("materialChanges");

            if (materialChanges == null || materialChanges.isEmpty()) {
                throw new RuntimeException("未找到要修改的物料信息");
            }

            BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

            for (Map<String, Object> change : materialChanges) {
                Long structureId = getLongValue(change, "structureId");
                if (structureId == null) {
                    continue;
                }

                BomStructure structure = bomStructureService.getById(structureId);
                if (structure == null) {
                    log.warn("BOM结构项不存在: structureId={}", structureId);
                    continue;
                }

                // 确保在正确的版本中操作
               if (!structure.getBomVersionId().equals(targetVersion.getId())) {
                    structure = copyStructureToNewVersion(structure, targetVersion.getId());
                }
//
//                // 记录原始值用于变更历史
                Map<String, Object> originalValues = recordOriginalValues(structure);

                // 修改物料的关键属性
                if (change.containsKey("itemCode")) {
                    structure.setItemCode(getStringValue(change, "itemCode"));
                }
                if (change.containsKey("itemName")) {
                    structure.setItemName(getStringValue(change, "itemName"));
                }
                if (change.containsKey("itemType")) {
                    structure.setItemType(getIntegerValue(change, "itemType"));
                }
                if (change.containsKey("specification")) {
                    structure.setSpecification(getStringValue(change, "specification"));
                }
                if (change.containsKey("unit")) {
                    structure.setUnit(getStringValue(change, "unit"));
                }
                if (change.containsKey("isKeyItem")) {
                    structure.setIsKeyItem(getIntegerValue(change, "isKeyItem"));
                }
                if (change.containsKey("isOptional")) {
                    structure.setIsOptional(getIntegerValue(change, "isOptional"));
                }

                structure.setUpdateTime(new Date());
                bomStructureService.updateById(structure);

                // 记录详细变更信息
                recordMaterialChange(changeLog, structure, originalValues, change);

                log.info("修改物料信息成功: structureId={}, itemCode={}",
                    structure.getId(), structure.getItemCode());
            }

        } catch (Exception e) {
            log.error("修改物料信息失败: changeLogId={}", changeLog.getId(), e);
            throw new RuntimeException("修改物料信息失败: " + e.getMessage());
        }
    }

    /**
     * 复制结构项到新版本
     * @param originalStructure
     * @param newVersionId
     * @return
     */
    private BomStructure copyStructureToNewVersion(BomStructure originalStructure, Long newVersionId) {
        log.info("复制结构项到新版本: structureId={}, newVersionId={}", originalStructure.getId(), newVersionId);

        BomStructure newStructure = new BomStructure();
        BeanUtils.copyProperties(originalStructure,newStructure);
        newStructure.setBomVersionId(newVersionId);
        bomStructureService.save(newStructure);
        return newStructure;
    }

    /**
     * 验证变更请求
     */
    private void validateChangeRequest(BomChangeLog changeLog) {
        if (changeLog.getBomId() == null) {
            throw new RuntimeException("BOM ID不能为空");
        }

        if (changeLog.getChangeType() == null) {
            throw new RuntimeException("变更类型不能为空");
        }

        if (changeLog.getChangeObject() == null) {
            throw new RuntimeException("变更对象不能为空");
        }

        if (changeLog.getChangeReason() == null || changeLog.getChangeReason().trim().isEmpty()) {
            throw new RuntimeException("变更原因不能为空");
        }

        if (changeLog.getChangeApplicantId() == null) {
            throw new RuntimeException("变更申请人不能为空");
        }

        // 验证BOM是否存在
        BomMaster bomMaster = bomMasterService.getById(changeLog.getBomId());
        if (bomMaster == null) {
            throw new RuntimeException("关联的BOM不存在");
        }
    }

    /**
     * 添加审批意见到变更内容
     */
    private void addApprovalComments(BomChangeLog changeLog, String approvalComments) {
        if (approvalComments != null && !approvalComments.trim().isEmpty()) {
            try {
                Map<String, Object> content = parseChangeContent(changeLog.getChangeContent());
                content.put("approvalComments", approvalComments);
                content.put("approvalTime", new Date());
                changeLog.setChangeContent(objectMapper.writeValueAsString(content));
            } catch (JsonProcessingException e) {
                log.warn("添加审批意见失败: {}", e.getMessage());
            }
        }
    }

    /**
     * 根据BOM ID查询变更记录
     */
    public List<BomChangeLog> getChangeLogsByBomId(Long bomId) {
        QueryWrapper<BomChangeLog> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", bomId)
            .orderByDesc("apply_time");
        return this.list(wrapper);
    }

    /**
     * 根据变更状态查询变更记录
     */
    public List<BomChangeLog> getChangeLogsByStatus(Integer changeStatus) {
        QueryWrapper<BomChangeLog> wrapper = new QueryWrapper<>();
        wrapper.eq("change_status", changeStatus)
            .orderByDesc("apply_time");
        return this.list(wrapper);
    }

    /**
     * 获取变更类型名称
     */
    public String getChangeTypeName(Integer changeType) {
        switch (changeType) {
            case 1: return "新增";
            case 2: return "修改";
            case 3: return "删除";
            case 4: return "替换";
            default: return "未知类型";
        }
    }

    /**
     * 获取变更对象名称
     */
    public String getChangeObjectName(Integer changeObject) {
        switch (changeObject) {
            case 1: return "BOM基本信息";
            case 2: return "BOM结构";
            case 3: return "物料信息";
            default: return "未知对象";
        }
    }

    /**
     * 获取变更状态名称
     */
    public String getChangeStatusName(Integer changeStatus) {
        switch (changeStatus) {
            case 1: return "待审批";
            case 2: return "已批准";
            case 3: return "已拒绝";
            case 4: return "已实施";
            default: return "未知状态";
        }
    }

    /**
     * 生成变更影响分析报告
     */
    public String generateImpactAnalysis(BomChangeLog changeLog) {
        StringBuilder analysis = new StringBuilder();
        analysis.append("变更影响分析报告:\n");
        analysis.append("变更类型: ").append(getChangeTypeName(changeLog.getChangeType())).append("\n");
        analysis.append("变更对象: ").append(getChangeObjectName(changeLog.getChangeObject())).append("\n");
        analysis.append("变更原因: ").append(changeLog.getChangeReason()).append("\n");

        // 分析对采购的影响
        analysis.append("\n采购影响:\n");
        analysis.append("- 可能需要重新评估供应商\n");
        analysis.append("- 可能影响采购周期和成本\n");

        // 分析对生产的影响
        analysis.append("\n生产影响:\n");
        analysis.append("- 可能需要调整生产工艺\n");
        analysis.append("- 可能影响生产计划和排程\n");

        // 分析对库存的影响
        analysis.append("\n库存影响:\n");
        analysis.append("- 可能产生呆滞库存\n");
        analysis.append("- 可能需要重新盘点相关物料\n");

        // 分析对成本的影响
        analysis.append("\n成本影响:\n");
        analysis.append("- 需要重新核算产品成本\n");
        analysis.append("- 可能影响项目预算\n");

        return analysis.toString();
    }

    /**
     * 批量审批变更请求
     */
    @Transactional
    public void batchApproveChanges(List<Long> changeLogIds, Long approverId, String approverName, String batchComments) {
        log.info("批量审批BOM变更: changeLogIds={}, approverId={}", changeLogIds, approverId);

        for (Long changeLogId : changeLogIds) {
            try {
                approveChange(changeLogId, approverId, approverName, batchComments);
            } catch (Exception e) {
                log.error("批量审批失败，变更记录ID: {}, 错误: {}", changeLogId, e.getMessage());
                // 继续处理其他记录，不中断整个批量操作
            }
        }

        log.info("批量审批完成，共处理{}条记录", changeLogIds.size());
    }

    /**
     * 批量拒绝变更请求
     */
    @Transactional
    public void batchRejectChanges(List<Long> changeLogIds, Long approverId, String approverName, String rejectReason) {
        log.info("批量拒绝BOM变更: changeLogIds={}, approverId={}", changeLogIds, approverId);

        for (Long changeLogId : changeLogIds) {
            try {
                rejectChange(changeLogId, approverId, approverName, rejectReason);
            } catch (Exception e) {
                log.error("批量拒绝失败，变更记录ID: {}, 错误: {}", changeLogId, e.getMessage());
            }
        }

        log.info("批量拒绝完成，共处理{}条记录", changeLogIds.size());
    }

    /**
     * 撤销变更请求（仅限申请人在待审批状态下操作）
     */
    @Transactional
    public void withdrawChange(Long changeLogId, Long applicantId) {
        log.info("撤销BOM变更请求: changeLogId={}, applicantId={}", changeLogId, applicantId);

        BomChangeLog changeLog = this.getById(changeLogId);
        if (changeLog == null) {
            throw new RuntimeException("变更记录不存在");
        }

        if (!changeLog.getChangeApplicantId().equals(applicantId)) {
            throw new RuntimeException("只能撤销自己申请的变更");
        }

        if (changeLog.getChangeStatus() != 1) {
            throw new RuntimeException("只有待审批状态的变更才能撤销");
        }

        // 删除变更记录或标记为已撤销
        changeLog.setChangeReason(changeLog.getChangeReason() + " [已撤销]");
        changeLog.setUpdateTime(new Date());
        this.updateById(changeLog);

        // 或者直接删除记录
         this.removeById(changeLogId);

        log.info("BOM变更请求撤销成功: changeLogId={}", changeLogId);
    }

    /**
     * 获取变更详情
     * @param id
     * @return
     */
    @Override
    public BomChangeLogVO getChangeLogDetail(Long id) {
        return null;
    }

    /**
     * 获取变更统计信息
     */
    public Map<String, Object> getChangeStatistics(Long bomId) {
        Map<String, Object> statistics = new HashMap<>();

        QueryWrapper<BomChangeLog> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", bomId);

        List<BomChangeLog> allChanges = this.list(wrapper);

        // 按状态统计
        long pendingCount = allChanges.stream().filter(c -> c.getChangeStatus() == 1).count();
        long approvedCount = allChanges.stream().filter(c -> c.getChangeStatus() == 2).count();
        long rejectedCount = allChanges.stream().filter(c -> c.getChangeStatus() == 3).count();
        long implementedCount = allChanges.stream().filter(c -> c.getChangeStatus() == 4).count();

        statistics.put("totalChanges", allChanges.size());
        statistics.put("pendingCount", pendingCount);
        statistics.put("approvedCount", approvedCount);
        statistics.put("rejectedCount", rejectedCount);
        statistics.put("implementedCount", implementedCount);

        // 按类型统计
        long addCount = allChanges.stream().filter(c -> c.getChangeType() == 1).count();
        long modifyCount = allChanges.stream().filter(c -> c.getChangeType() == 2).count();
        long deleteCount = allChanges.stream().filter(c -> c.getChangeType() == 3).count();
        long replaceCount = allChanges.stream().filter(c -> c.getChangeType() == 4).count();

        statistics.put("addCount", addCount);
        statistics.put("modifyCount", modifyCount);
        statistics.put("deleteCount", deleteCount);
        statistics.put("replaceCount", replaceCount);

        return statistics;
    }



    /**
     * 创建变更内容JSON
     */
    public String createChangeContentJson(Map<String, Object> changeData) {
        try {
            return objectMapper.writeValueAsString(changeData);
        } catch (JsonProcessingException e) {
            log.error("创建变更内容JSON失败: {}", e.getMessage());
            return "{}";
        }
    }



    /**
     * 设置结构项基本信息
     */
    private void setStructureBasicInfo(BomStructure structure, Map<String, Object> itemData) {
        structure.setItemId(getLongValue(itemData, "itemId"));
        structure.setItemCode(getStringValue(itemData, "itemCode"));
        structure.setItemName(getStringValue(itemData, "itemName"));
        structure.setItemType(getIntegerValue(itemData, "itemType"));
        structure.setSpecification(getStringValue(itemData, "specification"));
        structure.setUnit(getStringValue(itemData, "unit"));
        structure.setQuantity(getBigDecimalValue(itemData, "quantity"));
        structure.setScrapRate(getBigDecimalValue(itemData, "scrapRate"));
    }

    /**
     * 设置结构项层级信息
     */
    private void setStructureHierarchy(BomStructure structure, Map<String, Object> itemData, Long versionId) {
        structure.setParentItemId(getLongValue(itemData, "parentItemId"));
        structure.setLevelNo(getIntegerValue(itemData, "levelNo"));

        // 自动计算序号
        Integer seqNo = getIntegerValue(itemData, "seqNo");
        if (seqNo == null) {
            seqNo = getNextSequenceNumber(versionId, structure.getParentItemId());
        }
        structure.setSeqNo(seqNo);
    }
    /**
     * 设置供应商和价格信息
     */
    private void setStructureSupplierInfo(BomStructure structure, Map<String, Object> itemData) {
        structure.setSupplierId(getLongValue(itemData, "supplierId"));
        structure.setSupplierName(getStringValue(itemData, "supplierName"));
        structure.setUnitPrice(getBigDecimalValue(itemData, "unitPrice"));
        structure.setTotalPrice(getBigDecimalValue(itemData, "totalPrice"));
        structure.setLeadTime(getIntegerValue(itemData, "leadTime"));
    }

    /**
     * 设置其他属性
     */
    private void setStructureOtherInfo(BomStructure structure, Map<String, Object> itemData) {
        structure.setIsKeyItem(getIntegerValue(itemData, "isKeyItem"));
        structure.setIsOptional(getIntegerValue(itemData, "isOptional"));
        structure.setSubstituteGroup(getStringValue(itemData, "substituteGroup"));
        structure.setRemark(getStringValue(itemData, "remark"));
        structure.setCreateTime(new Date());
        structure.setUpdateTime(new Date());
    }

    /**
     * 删除BOM基本信息（废弃BOM）
     */
    private void deleteBomBasicInfo(BomChangeLog changeLog, Map<String, Object> changeContent) {
        BomMaster bomMaster = bomMasterService.getById(changeLog.getBomId());
        if (bomMaster == null) {
            throw new RuntimeException("BOM不存在");
        }

        // 设置为废弃状态而不是物理删除
        bomMaster.setStatus(StatusEnum.FQ.getCode()); // 已废弃
        bomMaster.setExpireDate(new Date());
        bomMaster.setUpdateTime(new Date());
        bomMasterService.updateById(bomMaster);

        log.info("BOM已废弃: bomId={}, bomCode={}", bomMaster.getId(), bomMaster.getBomCode());
    }

    /**
     * 删除BOM结构项
     */
    private void deleteBomStructureItems(BomChangeLog changeLog, Map<String, Object> changeContent) {
        List<Long> structureIds = (List<Long>) changeContent.get("deleteStructureIds");
        if (structureIds == null || structureIds.isEmpty()) {
            throw new RuntimeException("未指定要删除的结构项");
        }

        BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

        for (Long structureId : structureIds) {
            BomStructure structure = bomStructureService.getById(structureId);
            if (structure != null) {
                // 检查是否有子项，如果有则需要先处理子项
                checkAndHandleChildItems(structure, targetVersion.getId());

                // 执行删除
                bomStructureService.removeById(structureId);
                log.info("删除BOM结构项: structureId={}, itemCode={}", structureId, structure.getItemCode());
            }
        }
    }

    /**
     * 从BOM中删除物料
     */
    private void deleteMaterialFromBom(BomChangeLog changeLog, Map<String, Object> changeContent) {
        List<String> itemCodes = (List<String>) changeContent.get("deleteItemCodes");
        if (itemCodes == null || itemCodes.isEmpty()) {
            throw new RuntimeException("未指定要删除的物料编码");
        }

        BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

        QueryWrapper<BomStructure> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_version_id", targetVersion.getId())
            .in("item_code", itemCodes);

        List<BomStructure> structures = bomStructureService.list(wrapper);
        for (BomStructure structure : structures) {
            bomStructureService.removeById(structure.getId());
            log.info("从BOM中删除物料: itemCode={}, structureId={}", structure.getItemCode(), structure.getId());
        }
    }

    /**
     * 替换BOM基本信息
     */
    private void replaceBomBasicInfo(BomChangeLog changeLog, Map<String, Object> changeContent) {
        // 替换逻辑类似于修改，但是会完全覆盖原有信息
        modifyBomBasicInfo(changeLog, changeContent);
    }

    /**
     * 替换BOM结构
     */
    private void replaceBomStructure(BomChangeLog changeLog, Map<String, Object> changeContent) {
        BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

        // 获取替换映射关系
        List<Map<String, Object>> replacements =
            (List<Map<String, Object>>) changeContent.get("replacements");

        if (replacements == null || replacements.isEmpty()) {
            throw new RuntimeException("未找到替换映射关系");
        }

        for (Map<String, Object> replacement : replacements) {
            Long oldStructureId = getLongValue(replacement, "oldStructureId");
            Map<String, Object> newStructureData =
                (Map<String, Object>) replacement.get("newStructureData");

            if (oldStructureId != null && newStructureData != null) {
                // 删除旧结构项
                bomStructureService.removeById(oldStructureId);

                // 创建新结构项
                BomStructure newStructure = new BomStructure();
                newStructure.setBomVersionId(targetVersion.getId());
                setStructureBasicInfo(newStructure, newStructureData);
                setStructureHierarchy(newStructure, newStructureData, targetVersion.getId());
                setStructureSupplierInfo(newStructure, newStructureData);
                setStructureOtherInfo(newStructure, newStructureData);

                bomStructureService.save(newStructure);

                log.info("替换BOM结构项: oldId={}, newId={}",
                    oldStructureId, newStructure.getId());
            }
        }
    }

    /**
     * 在BOM中替换物料
     */
    private void replaceMaterialInBom(BomChangeLog changeLog, Map<String, Object> changeContent) {
        BomVersion targetVersion = getOrCreateTargetVersion(changeLog);

        List<Map<String, Object>> materialReplacements =
            (List<Map<String, Object>>) changeContent.get("materialReplacements");

        if (materialReplacements == null || materialReplacements.isEmpty()) {
            throw new RuntimeException("未找到物料替换信息");
        }

        for (Map<String, Object> replacement : materialReplacements) {
            String oldItemCode = getStringValue(replacement, "oldItemCode");
            String newItemCode = getStringValue(replacement, "newItemCode");

            if (oldItemCode != null && newItemCode != null) {
                // 查找使用旧物料的所有结构项
                QueryWrapper<BomStructure> wrapper = new QueryWrapper<>();
                wrapper.eq("bom_version_id", targetVersion.getId())
                    .eq("item_code", oldItemCode);

                List<BomStructure> structures = bomStructureService.list(wrapper);

                for (BomStructure structure : structures) {
                    // 更新为新物料
                    structure.setItemCode(newItemCode);
                    structure.setItemName(getStringValue(replacement, "newItemName"));
                    structure.setItemId(getLongValue(replacement, "newItemId"));

                    // 更新其他可能变化的属性
                    if (replacement.containsKey("newSpecification")) {
                        structure.setSpecification(getStringValue(replacement, "newSpecification"));
                    }
                    if (replacement.containsKey("newUnit")) {
                        structure.setUnit(getStringValue(replacement, "newUnit"));
                    }
                    if (replacement.containsKey("newUnitPrice")) {
                        structure.setUnitPrice(getBigDecimalValue(replacement, "newUnitPrice"));
                    }

                    structure.setUpdateTime(new Date());
                    bomStructureService.updateById(structure);

                    log.info("替换物料: oldItemCode={}, newItemCode={}, structureId={}",
                        oldItemCode, newItemCode, structure.getId());
                }
            }
        }
    }


    // ==================== 工具方法 ====================

    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }

    private Long getLongValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        try {
            return Long.parseLong(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private Integer getIntegerValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private BigDecimal getBigDecimalValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        if (value instanceof Number) {
            return BigDecimal.valueOf(((Number) value).doubleValue());
        }
        try {
            return new BigDecimal(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    private Date getDateValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return null;
        if (value instanceof Date) {
            return (Date) value;
        }
        if (value instanceof Long) {
            return new Date((Long) value);
        }
        // 可以根据需要添加更多日期格式解析逻辑
        return null;
    }
}
